package com.tanjun.data.components;


import com.fasterxml.jackson.databind.ObjectMapper;
import com.tanjun.common.enums.RedisCacheEnum;
import org.codehaus.commons.nullanalysis.Nullable;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.stereotype.Component;

import java.util.Arrays;
import java.util.List;
import java.util.concurrent.TimeUnit;

@Component
public class CloudCacheManager {

    @Autowired
    private RedisTemplate<String, Object> redisTemplate;

    @Autowired
    private ObjectMapper objectMapper;


    /**
     * 判断是否存在可以
     *
     * @param key key
     * @return 存在返回true
     */
    public boolean hasKey(String key) {
        return redisTemplate.hasKey(key);
    }

    /**
     * 删除key
     *
     * @param keys 1-n个key
     */
    public void delKeys(String... keys) {
        if (keys == null || keys.length == 0) {
            return;
        }
        redisTemplate.delete(Arrays.asList(keys));
    }

    /**
     * 获取值
     *
     * @param key   key
     * @param clazz 返回类型
     * @param <T>   返回类型
     * @return
     */
    public <T> T getValue(String key, Class<T> clazz) {
        Object obj = redisTemplate.opsForValue().get(key);
        if(obj==null){
            return null;
        }
        return objectMapper.convertValue(obj, clazz);
    }

    /**
     * 获取值
     *
     * @param key   key
     * @return
     */
    public String getString(String key) {
        return (String) redisTemplate.opsForValue().get(key) ;
    }

    /**
     * 保存值
     *
     * @param key
     * @param data
     * @param expireSeconds
     */
    public void saveValue(String key, Object data, Long expireSeconds) {
        redisTemplate.opsForValue().set(key, data, expireSeconds, TimeUnit.SECONDS);
    }

    public void saveValue(String key, Object data) {
        redisTemplate.opsForValue().set(key, data);
    }

    /**
     * 向redis中添加缓存
     * @param cacheEnum 缓存枚举
     * @param key 缓存key @Nullable
     * @param data 缓存数据
     */
    public void saveValue(RedisCacheEnum cacheEnum, @Nullable String key, Object data){
        redisTemplate.opsForValue().set(getKey(cacheEnum,key),
                data,
                cacheEnum.getExpire(),
                TimeUnit.SECONDS);
    }

    /**
     * 获取缓存key
     * @param cacheEnum 缓存枚举
     * @param key 缓存key  @Nullable
     * @return 返回缓存值
     */
    public String getString(RedisCacheEnum cacheEnum, @Nullable String key){
        return (String) redisTemplate.opsForValue().get(getKey(cacheEnum,key));
    }

    public <T> T getValue(RedisCacheEnum cacheEnum, @Nullable String key, Class<T> clszz) {
      return this.getValue(getKey(cacheEnum,key),clszz);
    }

    /**
     * 删除缓存
     * @param cacheEnum 缓存类型
     * @param key key @Nullable
     */
    public void delKey(RedisCacheEnum cacheEnum, @Nullable String key){
        redisTemplate.delete(getKey(cacheEnum,key));
    }


    private String getKey(RedisCacheEnum cacheEnum,@Nullable String key) {
        return cacheEnum.getKey()+(key!=null?key:"");
    }

    public <T> List<T> getList(String key, Class<T> clazz) {
        List<Object> list= redisTemplate.opsForList().range(key, 0, -1);
        if(list==null){
            return null;
        }
        return list.stream().map(item -> objectMapper.convertValue(item, clazz)).toList();
    }

    public <T> List<T> getList(RedisCacheEnum cacheEnum,@Nullable String key, Class<T> clazz){
        return this.getList(getKey(cacheEnum,key),clazz);
    }
}
